Add-PSSnapin Microsoft.Sharepoint.Powershell
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Sharepoint") 
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Sharepoint.Administration") 


########### Blocked Sites ##############
$BlockedSites = @();
$BlockedSites += "Http://myciena.portsoldev.com"
$BlockedSites += "http://psidciena/SiteS/appcatalog"
########################################


Function Get-FolderName() {
    $app = new-object -com Shell.Application
    $folder = $app.BrowseForFolder(0, "Select Folder", 0, "C:\")
    if ($folder.Self.Path -ne "") {write-host "You selected " $folder.Self.Path}
    return $folder.Self.Path
}
 
Function UploadFile($file, $web, $folderList) {
    $fileUrl = $folderList.Url + "/" + $file.Name;
    write-host "Uploading file " $file "to" $folderList
    $galleryFile=$web.GetFile($fileUrl)
    $stream = [IO.File]::OpenRead($file.fullname) 
    $result = $true
    try {
        if ($isPubWeb) {
            if($galleryFile.CheckOutStatus -eq "None") {
                $galleryFile.CheckOut()
            }
            $folderList.Files.Add($fileUrl,$stream,$true) 
            $galleryFile.CheckIn("Check In")
            $galleryFile.Publish("Published")
            $galleryFile.Approve("Approved")
        } 
        else { 
            if($galleryFile.CheckOutStatus -eq "None") {
                $galleryFile.CheckOut()
            }
            $folderList.Files.Add($fileUrl,$stream,$true)
            try {
                $galleryFile.CheckIn("Check In")
            }
            catch {
                Write-Host "Unable to check in file"
            }
        }
    } catch {
        $result = $false
    }
    $folderList.Update()
    if ($result) {write-host "Uploaded" -foregroundcolor "green"}
    $stream.close()
    return $result
}

Function ApplyMasterPage($fileUrl, $site) {
    $result = $true
    $fullUrl = New-Object System.Uri($fileUrl)
    $masterUri = $fullUrl.AbsolutePath.replace("%20"," ")
    write-host "Setting Master Url to: " $masterUri
    try {
        foreach ($subweb in $site.AllWebs) {
            write-host "setting master page for web " $subweb.url
            $subweb.MasterUrl = $masterUri
            $subweb.CustomMasterUrl = $masterUri
            $subweb.Update();
            $subweb.Dispose();
        }
    } catch {
        $result = $false
        Write-Host $_ 
    }

    return $result
}

$sites =  Get-SPWebApplication | Get-SPSite 

$SourceFolder = Get-FolderName
if(!$SourceFolder) {return}

$AllFiles =   Get-ChildItem $SourceFolder | ? {$_.psIsContainer -eq $False} | foreach -Process {$_.FullName} 
$AllFolders = Get-ChildItem -Recurse $SourceFolder | ? {!$_.psIsContainer -eq $False} | foreach -Process {$_.FullName} 
write-host "folders" $AllFolders
write-host "files" $AllFiles

foreach ($site in $sites) {
    if ($site.url.contains("/personal/")) { continue }
    if ($BlockedSites -contains $site.Url) { continue }
        
    Write-Host "-------------------------------------------------------------------"
    Write-Host "Working with site: " $site.url
    $web = $site.RootWeb; 
    $isPubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web)
    $folderList = ($web).GetFolder("_catalogs/masterpage")
    $result = $true
    
    foreach ($file in $AllFiles) {
        if (!$result) {break}
        $f = Get-Item $file
        $result = $result -and (UploadFile $f $web $folderList)
        if ($f.Extension -eq ".master") {
            $fileUrl = $web.Url + "/_catalogs/masterpage/" + $f.Name; 
            $result = $result -and (ApplyMasterPage $fileUrl $site)
        }
    }
    
    if ($result) {
        foreach ($Folder in $AllFolders) {
            $CurrentFolder = Get-Item $Folder 
            $FolderRelativePath = (Get-Item $CurrentFolder).FullName.Substring($SourceFolder.length) 
            $AllFilesInSubfolder =   Get-ChildItem $CurrentFolder | ? {$_.psIsContainer -eq $False} | foreach -Process {$_.FullName} 
            $FolderURL = $site.url + "/_catalogs/masterpage/"
            $SiteFolder = $folderList.SubFolders.Add($FolderURL + (Get-Item $CurrentFolder).Name) #, [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, (Get-Item $CurrentFolder).Name)
            foreach ($file in $AllFilesInSubfolder) {
                $f = Get-Item $file
                $result = $result -and (UploadFile $f $web $SiteFolder)
            }
        }
        $web.Update()
    }
    $web.dispose()
    $site.dispose()
}
Write-Host "Finished" -foregroundcolor "green"